﻿bob.ns.setNs('bob.code.module', {

    //v.2
    ModuleObserver: function () {
        var self = this;

        var _modules = {};
        var _onModuleLoaded = bob.event.namedEvent(this, 'moduleLoaded');

        var _isLoaded = function (sModule) {
            return !bob.utils.isUndefined(_modules[sModule]);
        };

        this.setLoaded = function (sModule, arg) {
            if (!bob.utils.isString(sModule) || bob.utils.isNullOrWhiteSpace(sModule)) {
                throw new Error('Wrong argument: sModule.');
            }
            if (_isLoaded(sModule)) {
                throw new Error(bob.string.formatString('Module "{0}" is already loaded.', sModule));
            }

            arg = bob.utils.ifUndefined(arg, null);
            _modules[sModule] = arg;

            _onModuleLoaded(sModule, _modules[sModule]);
        };

        this.whenLoaded = function (sModule, fnBody) {
            if (!bob.utils.isString(sModule) || bob.utils.isNullOrWhiteSpace(sModule)) {
                throw new Error('Wrong argument: sModule.');
            }
            if (!bob.utils.isFunction(fnBody)) {
                throw new Error('Wrong argument: fnBody.');
            }

            if (_isLoaded(sModule)) {
                fnBody(_modules[sModule]);
            }
            else {
                var handler = self.add_moduleLoaded(function (moduleName, arg) {
                    if (bob.utils.equals(moduleName, sModule)) {
                        fnBody(arg);
                        self.remove_moduleLoaded(handler);
                    }
                });
            }
        };
    }

    //setLoaded - implicitly from _last.

    //whenLoaded - implicitly from _last.

});
